package com.hsgene.generator.util.generator;

import java.util.HashMap;
import java.util.Random;

/**
 * 短信验证码生成器
 *
 * @author wangbing
 * @version 1.0, 2018/6/29
 */
public class SmsGenerator extends AbstractGenerator {

    /**
     * 默认短信验证码长度
     */
    private final static Integer DEFAULT_SMS_VERIFY_CODE_LENGTH = 4;

    /**
     * 短信验证码长度
     */
    private Integer verifyCodeLength;

    /**
     * 短信验证码生成器实例Map
     * key为验证码长度，即当验证码长度一致时返回同一个实例
     */
    private volatile static HashMap<Integer, SmsGenerator> instances;

    private SmsGenerator() {
        this(DEFAULT_SMS_VERIFY_CODE_LENGTH);
    }

    private SmsGenerator(Integer verifyCodeLength) {
        this.verifyCodeLength = verifyCodeLength;
    }

    private synchronized void initInstances() {
        instances = new HashMap<>(4);
    }

    /**
     * 单例模式实现短信验证码生成器Map
     * 以验证码长度为键存放启实例
     *
     * @return 短信验证码生成器Map
     */
    private static HashMap<Integer, SmsGenerator> getInstances() {
        if (instances == null) {
            synchronized (SmsGenerator.class) {
                if (instances == null) {
                    instances = new HashMap<>(4);
                }
            }
        }

        return instances;
    }

    /**
     * 单例获取短信验证码生成器
     *
     * @return 短信验证码生成器
     */
    public static SmsGenerator getInstance() {
        SmsGenerator result = getInstances().get(DEFAULT_SMS_VERIFY_CODE_LENGTH);
        if (result == null) {
            synchronized (SmsGenerator.class) {
                result = new SmsGenerator();
                instances.put(DEFAULT_SMS_VERIFY_CODE_LENGTH, result);
            }
        }

        return result;
    }

    /**
     * 单例获取短信验证码生成器
     *
     * @param verifyCodeLength 验证码长度
     * @return 短信验证码生成器
     */
    public static SmsGenerator getInstance(Integer verifyCodeLength) {
        SmsGenerator result = getInstances().get(verifyCodeLength);
        if (result == null) {
            synchronized (SmsGenerator.class) {
                result = new SmsGenerator(verifyCodeLength);
                instances.put(verifyCodeLength, result);
            }
        }

        return result;
    }

    @Override
    public String generate(String prefix) {
        return build(verifyCodeLength);
    }

    private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 根据长度生成随机验证码
     *
     * @param codeLength 验证码长度
     * @return 验证码
     */
    private static String build(int codeLength) {
        Random random = new Random();
        StringBuilder verifyCodeBuilder = new StringBuilder(codeLength);

        for (int i = 0; i < codeLength; i++) {
            int index = random.nextInt(10);
            verifyCodeBuilder.append(DIGITS[index]);
        }

        return verifyCodeBuilder.toString();
    }
}
